import localforage from 'localforage'
import LimitPromise from "@/utils/LimitPromise";
import {FileUtils} from "@/utils/FileUtils";
import Axios from 'axios'
import * as imageConversion from "@/dependent_modules/image-conversion";
import registerPromiseWorker from "promise-worker/register";

const limitPromise = new LimitPromise(3)
const cacheImgDb = localforage.createInstance({
  name: 'cacheImgDb'
}) // 二级缓存
// 缓存原图
const cacheImgDbSource = localforage.createInstance({
  name: 'cacheImgDbSource'
}) // 二级缓存

export interface Data {
  func: 'getItem' | 'toFirstNest' | 'delTask' | 'beforeunload';
  params: string;
  cacheId: string;
  isSource: boolean;
}

export interface ResultData {
  url: string;
  urlSource: string;
  cacheUrl: string;
  cacheId: string;
  dir: 'clearFinished' | 'getUrlFinished';
  isSource: boolean;
}

const limitFunc = new LimitPromise(1)

registerPromiseWorker(async function (data: Data) {
  if (data.func === 'getItem') {
    let url = data.params
    let cacheId = data.cacheId
    let isSource = data.isSource
    return limitFunc.call(async () => {
      let newVar = await cacheImgDb.getItem(url) as string;
      let s = await cacheImgDbSource.getItem(url) as string;
      let res = isSource ? s : newVar
      if (res) {
        return {
          url: newVar,
          urlSource: s,
          cacheUrl: url,
          cacheId,
          dir: 'getUrlFinished',
          isSource
        } as ResultData
      } else {
        await cacheImgDbSource.setItem(url, 'loading')
        await cacheImgDb.setItem(url, 'loading')
      }
    }, data.cacheId + "getItem")
      .then((res) => {
        if (res) {
          return res
        }
        const pro = limitPromise.call(async () => {
          let res1 = await Axios.get(url, {
            responseType: 'blob'
          })
          if (res1.status === 200) {
            let base64Source = await FileUtils.blob2Base64(res1.data)
            await cacheImgDbSource.setItem(url, base64Source)
            let base64 = await FileUtils.blob2Base64(await zipFile(res1.data))
            await cacheImgDb.setItem(url, base64)
            return {
              url: base64,
              urlSource: base64Source,
              cacheUrl: url,
              cacheId,
              dir: 'getUrlFinished',
              isSource
            } as ResultData
          }
        }, url)
        limitPromise.toFirstNest(url)
        return pro
      })
  } else if (data.func === 'toFirstNest') {
    limitPromise.toFirstNest(data.params)
  } else if (data.func === 'delTask') {
    limitFunc.delTask(data.cacheId + "getItem")
    if (!data.params) {
      return
    }
    let taskQueueItem = limitPromise.delTask(data.params);
    if (taskQueueItem) {
      let url = taskQueueItem.id
      let newVar = await cacheImgDbSource.getItem(url);
      if (newVar && newVar === 'loading') {
        await cacheImgDbSource.removeItem(url)
      }
      let newVar1 = await cacheImgDb.getItem(url);
      if (newVar1 && newVar1 === 'loading') {
        await cacheImgDb.removeItem(url)
      }
    }
  } else if (data.func === 'beforeunload') {
    return Promise.all([
      cacheImgDb.clear(),
      cacheImgDbSource.clear(),
    ])
  }
})

async function zipFile(file: Blob) {
  let blob = await imageConversion.compressAccurately(file, {
    size: 50,
  })
  return blob;
}
